package com.lmx.persistence.service;

import java.util.List;
import java.util.Optional;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.lmx.common.constants.CommonConstants;
import com.lmx.common.util.CommonUtil;
import com.lmx.persistence.service.common.BaseCrudServiceImpl;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerDrugProjectExe;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.NursingPlanExecute;
import com.lmx.repoDomain.tmodel.PersonLocationAnalysis;
import com.lmx.repoDomain.tmodel.PersonLocationAnalysisReport;
import com.lmx.repoDomain.tmodel.PersonLocationIoReport;
import com.lmx.repoDomain.tmodel.Room;
import com.lmx.repoDomain.tmodel.Tenant;

/**
 * 巡管分析service实现
 *
 * @author ytche
 * @date 2017年8月22日
 *
 */
@Service
public class PersonLocationAnalysisServiceImpl extends
		BaseCrudServiceImpl<PersonLocationAnalysis> implements
		PersonLocationAnalysisService {
	private Log logger = LogFactory.getLog(this.getClass());
	@Autowired
	private TenantService<Tenant> tenantService;
	@Autowired
	private EmployeeService<Employee> employeeService;
	@Autowired
	private NursingPlanExecuteService nursingExeSrv;
	@Autowired
	private CustomerDrugProjectExeService drugExeSrv;
	@Autowired
	private PersonLocationIOReportService positionIoService;
	@Autowired
	private CustomerService<Customer> customerService;
	@Autowired
	private DicttypeService dicService;

	@SuppressWarnings("rawtypes")
	@Autowired
	private NursingService nursingService;
	@Autowired
	private PersonLocationAnalysisReportService ananlysisReportSrv;

	@Override
	@Transactional
	public Boolean analysis(Integer beginTime) {
		Boolean rtn = false;
		List<Tenant> tenants = tenantService.findActiveTenant();
		for (Tenant tenant : tenants) {
			List<Employee> employees = employeeService.findByTenant(tenant
					.getId());
			for (Employee employee : employees) {
				try {
					new Thread() {
						@Override
						public void run() {
							List<Customer> customers = customerService
									.getCustomerByEID(employee.getId(), false);
							if (customers == null || customers.size() == 0) {
								return;
							}
							// 默认对昨天的数据进行统计
							Integer time = beginTime == null ? (int) (System
									.currentTimeMillis() / 1000) - 3600 * 24
									: beginTime;
							Integer startTime = CommonUtil.getDayBegin(time);
							Integer endTime = startTime + 3600 * 24;
							List<PersonLocationIoReport> ioReports = positionIoService
									.findOfDay(employee.getId(),
											beginTime.longValue() * 1000);
							List<NursingPlanExecute> nursingExes = nursingExeSrv
									.findExeOfCustomers(tenant.getId(),
											customers, startTime, endTime,
											employee);
							List<CustomerDrugProjectExe> drugExes = drugExeSrv
									.findByEmployeeAndCustomer(tenant.getId(),
											customers, startTime, endTime,
											employee);
							analysisEmployeeExe(employee, ioReports,
									nursingExes, drugExes, beginTime, customers);
						}
					}.start();
				} catch (Exception e) {
					logger.error("分析员工每日护理执行出错,员工Id为" + employee.getId(), e);
				}
			}
		}
		rtn = true;
		return rtn;
	}

	/**
	 * 分析员工的位置信息和执行情况的匹配度
	 *
	 * @author ytche
	 * @param employee
	 * @param ioReports
	 * @param nursingExes
	 * @param drugExes
	 * @param beginTime
	 * @param customers
	 * @date 2017年8月24日 下午3:18:40
	 */
	private void analysisEmployeeExe(Employee employee,
			List<PersonLocationIoReport> ioReports,
			List<NursingPlanExecute> nursingExes,
			List<CustomerDrugProjectExe> drugExes, Integer beginTime,
			List<Customer> customers) {
		PersonLocationAnalysisReport report = new PersonLocationAnalysisReport();
		report.setTenant(employee.getTenant());
		// 统计的基础数据
		report.setGenerateTime(beginTime);
		report.setEmployee(employee);
		Integer serviceNum = this.nursingService.getDayServiceNum(customers);
		report.setServiceNum(serviceNum);
		Integer exeNum = (nursingExes == null ? 0 : nursingExes.size())
				+ (drugExes == null ? 0 : drugExes.size());
		report.setExeNum(exeNum);
		// 统计的分析数据
		List<PersonLocationAnalysis> analysisList = Lists.newArrayList();
		// 护理服务执行情况分析
		for (NursingPlanExecute nursingExe : nursingExes) {
			PersonLocationAnalysis analysis = new PersonLocationAnalysis();
			analysis.setType(this.dicService
					.findById(CommonConstants.LOCATION_ANALYSIS_TYPE.NURSING
							.lable()));
			analysis.setPlanItemExe(nursingExe);
			analysis.setEmployee(employee);
			analysis.setTenant(employee.getTenant());
			Room room = nursingExe.getItemProject().getProject().getCustomer()
					.getBed().getRoom();
			Integer startTime = nursingExe.getExeStartTime();
			analysisPositionMatch(ioReports, analysis, room, startTime);
			super.save(analysis);
			analysisList.add(analysis);
		}
		// 用药执行情况分析
		for (CustomerDrugProjectExe drugExe : drugExes) {
			PersonLocationAnalysis analysis = new PersonLocationAnalysis();
			analysis.setType(this.dicService
					.findById(CommonConstants.LOCATION_ANALYSIS_TYPE.DRUG
							.lable()));
			analysis.setDrugExe(drugExe);
			analysis.setEmployee(employee);
			analysis.setTenant(employee.getTenant());
			Room room = drugExe.getCustomerDrug().getCustomer().getBed()
					.getRoom();
			Integer startTime = drugExe.getExeDate();
			analysisPositionMatch(ioReports, analysis, room, startTime);
			super.save(analysis);
			analysisList.add(analysis);
		}
		report.setAnalysises(analysisList);
		int misMatchNum = (int) analysisList
				.stream()
				.filter(p -> p.getCompleteStatus() == CommonConstants.DEFAULT_STATUS_NO_0)
				.count();
		report.setMisMatchNum(misMatchNum);
		this.ananlysisReportSrv.save(report);
	}

	/**
	 * 分析位置信息是否与执行情况匹配
	 *
	 * @author ytche
	 * @param ioLocationReports
	 *            出入房间统计list
	 * @param analysis
	 *            生成的分析信息
	 * @param room
	 *            房间
	 * @param startTime
	 *            执行的开始时间
	 *
	 * @date 2017年8月24日 下午3:17:54
	 */
	private void analysisPositionMatch(
			List<PersonLocationIoReport> ioLocationReports,
			PersonLocationAnalysis analysis, Room room, Integer startTime) {
		final Integer errorTime = 300;
		if (ioLocationReports == null || ioLocationReports.size() < 1) {
			analysis.setCompleteStatus(CommonConstants.DEFAULT_STATUS_NO_0);
		} else {
			Optional<PersonLocationIoReport> matchIo = ioLocationReports
					.stream()
					.filter(p -> p.getRoom().equals(room)
							&& startTime > (p.getInTime() - errorTime)
							&& startTime < (p.getOutTime())).findFirst();
			if (matchIo.isPresent()) {
				analysis.setCompleteStatus(CommonConstants.DEFAULT_STATUS_YES_1);
				analysis.setLocation(matchIo.get());
			} else {
				analysis.setCompleteStatus(CommonConstants.DEFAULT_STATUS_NO_0);
			}
		}
	}

}
